package com.mfcxy.annotations;

import java.lang.reflect.InvocationTargetException;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import org.apache.commons.beanutils.BeanUtils;

public class ConfirmDataValidator implements ConstraintValidator<ConfirmData, Object>{
		//当前字段
		private String field;
		//被验证的字段
		private String verifyField;

		/**
		 * 初始化验证器以准备 {@link #isValid(Object, ConstraintValidatorContext)}调用。
		 * 给定约束声明的约束注释通过。 < p / > 保证在使用此实例之前调用此方法 验证。
		 *
		 * @param constraintAnnotation实例，用于给定的约束声明
		 */
		@Override
		public void initialize(ConfirmData constraintAnnotation) {
			this.field = constraintAnnotation.field();
			this.verifyField = constraintAnnotation.verifyField();
		}

		/**
		 * 实现验证逻辑。 {@code值}的状态不可更改。 < p / > 该方法可以同时访问，必须确保线程安全 的实现。
		 * 
		 * @param值对象进行验证
		 * @param上下文，在其中评估约束
		 * @return {@code false}，如果{@code value}没有通过约束
		 */
		@Override
		public boolean isValid(Object value, ConstraintValidatorContext context) {
			// TODO Auto-generated method stub
			try {
				/*
				 * 什么是BeanUtils工具
				 * BeanUtils工具是一种方便我们对JavaBean进行操作的工具，是Apache组织下的产品。
				 * BeanUtils工具一般可以方便javaBean的哪些操作？
				 * 1）beanUtils 可以便于对javaBean的属性进行赋值。
				 * 2）beanUtils 可以便于对javaBean的对象进行赋值。
				 * 3）beanUtils可以将一个MAP集合的数据拷贝到一个javabean对象中。
				 */
				String fieldValue = BeanUtils.getProperty(value, field);
				String verifyFieldValue = BeanUtils.getProperty(value, verifyField);
				boolean valid = (fieldValue == null) && (verifyFieldValue == null);
				if (valid) {
					return true;
				}

				boolean match = (fieldValue != null) && fieldValue.equals(verifyFieldValue);
				if (!match) {
					//设置提示信息模板
					String messageTemplate = context.getDefaultConstraintMessageTemplate();
					context.disableDefaultConstraintViolation();
					context.buildConstraintViolationWithTemplate(messageTemplate).addNode(verifyField)
							.addConstraintViolation();
				}
				return match;
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			}
			return true;
		}
}
